//
// Created by entaoyang@163.com on 2017/10/25.
// Copyright (c) 2017 yet.net. All rights reserved.
//

import Foundation


public enum FileCategory: String {
    case home = "@home"
    case doc = "@doc"
    case cache = "@cache"
    case temp = "@temp"

    var absolutePath: String {
        switch self {
        case .home:
            return NSHomeDirectory()
        case .temp:
            return NSTemporaryDirectory()
        case .doc:
            return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        case .cache:
            return NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
        }
    }
}

public class AppFile: FileBase {
    public let category: FileCategory
    public let path: String


    public init(category: FileCategory, paths: String...) {
        self.category = category
        self.path = build(paths: paths)
    }


    public var fullPath: String {
        buildPath(categoryPath, path)
    }
    public private(set) var fileManager: FileManager = FileManager.default
}

public extension AppFile {
    convenience init(file: AppFile, paths: String...) {
        self.init(category: file.category, paths: file.path, build(paths: paths))
    }


    convenience init(apppath: String) {
        if apppath.startWith(FileCategory.cache.rawValue) {
            self.init(category: .cache, paths:apppath.trimStart(FileCategory.cache.rawValue).trimStart("/"))
        } else if apppath.startWith(FileCategory.doc.rawValue) {
            self.init(category: .doc, paths:apppath.trimStart(FileCategory.doc.rawValue).trimStart("/"))
        } else if apppath.startWith(FileCategory.temp.rawValue) {
            self.init(category: .temp, paths:apppath.trimStart(FileCategory.temp.rawValue).trimStart("/"))
        } else if apppath.startWith(FileCategory.home.rawValue) {
            self.init(category: .home, paths:apppath.trimStart(FileCategory.home.rawValue).trimStart("/"))
        } else {
            fatalError("Only Support App path which start with @home, @doc, @cache, @temp")
        }
    }

    convenience init(fullpath: String) {
        if fullpath.startWith(FileCategory.cache.absolutePath) {
            self.init(category: .cache, paths: fullpath.trimStart(FileCategory.cache.absolutePath).trimStart("/"))
        } else if fullpath.startWith(FileCategory.doc.absolutePath) {
            self.init(category: .doc, paths: fullpath.trimStart(FileCategory.doc.absolutePath).trimStart("/"))
        } else if fullpath.startWith(FileCategory.temp.absolutePath) {
            self.init(category: .temp, paths: fullpath.trimStart(FileCategory.temp.absolutePath).trimStart("/"))
        } else if fullpath.startWith(FileCategory.home.absolutePath) {
            self.init(category: .home, paths: fullpath.trimStart(FileCategory.home.absolutePath).trimStart("/"))
        } else {
            fatalError("Only Support App path which start with @home, @doc, @cache, @temp")
        }
    }

    var categoryPath: String {
        self.category.absolutePath
    }


    //@doc/abc.txt
    var appPath: String {
        buildPath(category.rawValue, path)
    }
}


public func buildPath(_ paths: String...) -> String {
    build(paths: paths)
}

public func build(paths: [String]) -> String {
    var s = ""
    s.reserveCapacity(128)
    for p in paths {
        if s.isEmpty {
            s.append(p)
        } else if s.endWith("/") {
            s.append(p.trimStart("/"))
        } else if p.startWith("/") {
            s.append(p)
        } else {
            s.append("/")
            s.append(p)
        }
    }
    return s
}
